package org.xx.armory.commons;

import java.util.Collection;

/**
 * 树形结构。
 *
 * @param <E>
 *         树形结构关联的类型。
 */
public interface Tree<E> {
    /**
     * 获取根节点集合。
     *
     * @return 根节点集合。
     */
    Collection<? extends Node<E>> roots();

    /**
     * 清除根节点。
     */
    void clear();

    /**
     * 添加一个根节点。
     *
     * @param rootObj
     *         根节点关联的对象。
     * @return 已添加的节点。
     * @throws IllegalArgumentException
     *         如果参数{@code obj}是{@code null}。
     */
    Node<E> add(
            E rootObj
    );

    /**
     * 树形结构中的每个节点。
     *
     * @param <E>
     *         节点关联的类型。
     */
    interface Node<E> {
        /**
         * 获取节点所属的树形结构。
         *
         * @return 节点所属的树形结构。
         */
        Tree<E> tree();

        /**
         * 获取节点关联的对象。
         *
         * @return 节点关联的对象。
         */
        E get();

        /**
         * 获取上级节点。
         *
         * @return 上级节点，如果当前节点是根节点则返回{@code null}。
         */
        Node<E> parent();

        /**
         * 获取所有子节点。
         *
         * @return 所有子节点，如果不存在子节点则返回空集合。
         */
        Collection<? extends Node<E>> children();

        /**
         * 获取此节点的深度，根节点的深度是{@code 1}。
         *
         * @return 此节点的深度。
         */
        int depth();

        /**
         * 加入新的子节点。
         *
         * @param childObj
         *         新的子节点关联的对象。
         * @return 新的子节点，该子节点关联到对象{@code childObj}。
         * @throws IllegalArgumentException
         *         如果参数{@code child}是{@code null}。
         */
        Node<E> add(
                E childObj
        );

        /**
         * 删除子节点。
         * <p>如果子节点不存在则不执行删除。</p>
         *
         * @param child
         *         待删除的子节点。
         * @throws IllegalArgumentException
         *         如果参数{@code child}是{@code null}。
         */
        void delete(
                Node<E> child
        );
    }
}
